<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
<script>
    // 默认绑定：常用的函数调用类型：独立函数调用
    // 可以把这个规则看作是无法应用其他规则的时候默认的规则，基本指向的是window
    // function fn(){
    //     console.log(this);// window
    // }
    // fn();
    //
    // const fn2 = function(){
    //     console.log(this);// window
    // }
    // fn2();
    //
    //
    // [1,2,3,4].forEach(function(){
    //     console.log(this);// window
    // })


    // 隐式绑定：如果函数调用时，前面存在调用它的对象，那么this就会隐式绑定到这个对象上
    // 当函数引用有上下文对象的时候（obj），隐式绑定规则会把函数中的this绑定到这个上下文对象上
    // const obj = {
    //     fn(){
    //         console.log(this===obj);
    //     },
    //     fn2:function(){
    //         console.log(this === obj)
    //     },
    //     fn3:()=>{
    //         // 箭头函数中的this与调用无关(箭头函数中自身没有this)
    //         console.log(this);
    //     }
    // }
    // // 隐式将this绑定至obj,obj是引用上下文对象
    // obj.fn();
    // obj.fn2();
    // obj.fn3();


    // * 隐式绑定可能会出现隐式丢失的问题 ：被隐式绑定的函数，会丢失了绑定对象
    // {
    //     const obj = {
    //         fn(){
    //             console.log(this);
    //         }
    //     }
    //     obj.fn();// obj
    //     const fn2 = obj.fn;
    //     fn2();// 丢失，this指向window
    // }


    // 显式绑定：指我们通过call、apply以及bind方法改变this的行为，相比隐式绑定，我们能清楚的感知 this 指向变化过程。
    // {
    //     function fn(){
    //         console.log("fn",this);
    //     }
    //     const obj = {
    //         fn(){
    //             console.log("obj->fn",this);
    //         }
    //     }
    //     // fn();// 默认绑定 window
    //     // obj.fn();// 隐式绑定 obj
    //     fn.call(this);
    //     fn.call(obj);
    // }


    // `new`绑定：构造函数只是一些使用new操作符被调用的函数,使用new调用函数的时候，会构造一新的对象，
    // 这个时候 就把新的对象绑定给了函数的this上
    {
        // 1- 调用函数Box
        // 2- 创建对象，并将对象赋值给当前this
        // 3- 将this进行返回
        function Box() {
            this.a = 1;
            this.b = 2;
            console.log(1111, this);
            this.fn();
        }

        Box.prototype.fn = function () {
            console.log(this);
        }
        const box = new Box();
        box.fn();
    }
</script>
</html>